9 - Building a Cash Register

Shut the Shop!

You are working for a large supermarket and the cash register has just failed. The boss is not happy as he can't make any money.

To save the day it happens that you let slip to your boss that you know JavaScript and can build a quick virtual cash register until head office sends support staff.

Your boss is over the moon and wants you to get started right away.

Create a new object called cashRegisterwith the property total initialized to 0.

Then change the property total to 2.99using dot notation.

//Create the object called cashRegister 
//and initialize its total property
var cashRegister = {
    total:0,
};
//Using dot notation change the total property
cashRegister.total = 2.99;
Manually Add It Up?

Great! The bossman can see that you can tell the cash register the total. But we need the cash register to do more.

Your boss wants a way to manually add the cost of each item. We have written the addmethod for you. There are two things we should note.

  1. We are using literal notation to include the method add.
  2. We've used the += operator. This is a shorthand way of saying

this.total = this.total + itemCost;
In general, a += b; means "add b to aand put the result of that addition back intoa. This is also available for the other basic arithmetic functions: -=*=, and /= do what you expect.

Use the add method to sum up the cost of the following four items.

  1. Eggs 0.98
  2. Milk 1.23
  3. Magazine 4.99
  4. Chocolate 0.45

If we only call the method once, it will just add the first item. So to add up the cost of four items, how many times will we have to call the method?

var cashRegister = {
    total:0,
    add: function(itemCost){
        this.total += itemCost;
    }
};
//call the add method for our items
cashRegister.add(0.98 + 1.23 + 4.99 + 0.45);
//Show the total bill
console.log('Your bill is '+cashRegister.total);
Short-Term Memory

But this method only works as long as you can remember the cost of every item in the store. We need something like a bar code scanner where just knowing the item name will automatically add the cost of that item to the total.

So we create a method called scan. This method takes some item parameter, and adds the cost of this item to the total.item is a string.

We also use a switch statement. Previously, we would have probably used multiple if-else statements. Here, things work in a similar way.

For example, if the item is "eggs" (line 8), we then call the add method, passing through 0.98 as the itemCost. This will add 0.98 to cashRegister.total. If instead the item is "milk" or"chocolate" or "magazine", the relevantitemCost is added. Note no default case is needed for this switch statement.

  1. Write the add method which has a single parameter, itemCost. It will add theitemCost to the total.
  2. We have partially written the scanmethod for you and started a switchstatement. Add the following 2 items to theswitch statement:

Finally, use the scan method to buy"eggs" twice and a "magazine" three times.

var cashRegister = {
    total: 0,
//insert the add method here    
    add: function(itemCost){
        this.total += itemCost;
    },
    
    scan: function (item) {
        switch (item) { 
        case "eggs": 
            this.add(0.98); 
            break;
        
        case "milk": 
            this.add(1.23); 
            break;
        
        //Add other 2 items here
        case "magazine":
            this.add(4.99);
            break;
        case "chocolate":
            this.add(0.45);
            break;
        
        }
        return true;
    }
};
//Scan 2 eggs and 3 magazines
cashRegister.scan("eggs");
cashRegister.scan("eggs");
cashRegister.scan("magazine");
cashRegister.scan("magazine");
cashRegister.scan("magazine");
//Show the total bill
console.log('Your bill is '+cashRegister.total);
I Have to Scan It More Than Once?

Is that a smile on the boss's face? Well, there was one until he realized that your system requires every item to be scanned individually. He finds this pretty inefficient and you probably agree. Let's get real—it was pretty annoying having to call the scan method five times in the previous exercise!

What can we do? What is the limitation of the scan method? Well, it has just one parameter, item, and you can't specify anything related to quantity.

Modify the scan method such that if we tell it the quantity of each item, it will be able to add the right amount to the total. Since you currently tell scan nothing about quantity, it may be useful to create another parameter.

Scan 4 of each item using your improvedscan method. Previously we would have needed to call scan 16 times! Now it is down to 4.

var cashRegister = {
    total:0,
    add: function(itemCost){
        this.total += itemCost;
    },
    scan: function(itemnumItems) {
        switch (item) {
        case "eggs": this.add(0.98 * numItems); break;
        case "milk": this.add(1.23 * numItems); break;
        case "magazine": this.add(4.99 * numItems); break;
        case "chocolate": this.add(0.45 * numItems); break;
        };
    }
};
// scan each item 4 times
cashRegister.scan("eggs", 4);
cashRegister.scan("milk", 4);
cashRegister.scan("magazine", 4);
cashRegister.scan("chocolate", 4);
//Show the total bill
console.log('Your bill is '+cashRegister.total);
Bleep Bleep

The boss looks down at his pager to see Register 8 needs assistance. They have scanned an item too many times and need to void the last transaction.

So he turns to you and says: "Okay JavaScript Ninja! What do we do now?!"

We need to keep track of how much the last transaction was. Modify the addmethod to keep track of the amount of the last transaction. This should be tracked in a new property, lastTransactionAmount.

Add a method called voidLastTransactionthat subtracts the last amount transacted from total.

Then use the new method to void the last item we scanned. Finally, scan only 3 of the same item instead.

var cashRegister = {
    total:0,
    //Dont forget to add your property
    add: function(itemCost) {
        this.total += itemCost;
        this.lastTransactionAmount = itemCost;
    },
    scan: function(item,quantity) {
        switch (item) {
            case "eggs": this.add(0.98 * quantity); break;
            case "milk": this.add(1.23 * quantity); break;
            case "magazine": this.add(4.99 * quantity); break;
            case "chocolate": this.add(0.45 * quantity); break;
        }
        return true;
    }
    //Add the voidLastTransaction Method here
    voidLastTransaction: function()
    {
        this.total -= this.lastTransactionAmount;
    },
};
cashRegister.scan('eggs',1);
cashRegister.scan('milk',1);
cashRegister.scan('magazine',1);
cashRegister.scan('chocolate',4);
//Void the last transaction and then add 3 instead
cashRegister.voidLastTransaction();
cashRegister.scan('chocolate',3);
//Show the total bill
console.log('Your bill is '+cashRegister.total);
Over the Moon

Great! The store is ticking along making money again. The boss is so happy you have just been given a bonus staff discount to the value of 20%.

However the current system doesn't know how to apply the different levels of staff discount that apply. Now the rest of the staff is not happy and demanding you make improvements!

Let's sort it out so that staff can get their well deserved discount

Create an object constructor calledStaffMember which takes two parameters—name and discountPercent. And then have the (public) properties name anddiscountPercent equal the parameters.

To help, we have already created two employees using this constructor. Sally and Bob already have their staff discount set up: Sally getting 5% off and Bob getting 10%.

Create a new instance of the object for yourself called me with your massive staff discount bonus of 20%.

// create a constructor for the StaffMember class
function StaffMember(namediscountPercent) {
    this.name = name;
    this.discountPercent = discountPercent;
}
var sally = new StaffMember("Sally",5);
var bob = new StaffMember("Bob",10);
//Create a StaffMember for yourself called me
var me = new StaffMember("Jesse", 20);
You Deserved It!

Whew! It's been a long day fixing cash registers and now let's actually apply our well-earned discount. Now that we have our objects representing the staff, let's update our cash register to actually apply the discount

On line 10 create a new object called me of type StaffMember for yourself with a staff discount of 20%

Create a new method calledapplyStaffDiscount in the cashRegisterobject which accepts a parameteremployee. When this method is called,cashRegister should apply the staff member's discountPercent to total.

Under the comment, 'Apply your staff discount by passing the me object, call your new applyStaffDiscount and pass the object me.

function StaffMember(name,discountPercent){
    this.name = name;
    this.discountPercent = discountPercent;
}
var sally = new StaffMember("Sally",5);
var bob = new StaffMember("Bob",10);
// Create yourself again as 'me' with a staff discount of 20%
var me = new StaffMember("Jesse", 20);
var cashRegister = {
    total:0,
    lastTransactionAmount: 0,
    add: function(itemCost){
        this.total += (itemCost || 0);
        this.lastTransactionAmount = itemCost;
    },
    scan: function(item,quantity){
        switch (item){
        case "eggs": this.add(0.98 * quantity); break;
        case "milk": this.add(1.23 * quantity); break;
        case "magazine": this.add(4.99 * quantity); break;
        case "chocolate": this.add(0.45 * quantity); break;
        }
        return true;
    },
    voidLastTransaction : function(){
        this.total -= this.lastTransactionAmount;
        this.lastTransactionAmount = 0;
    },
    // Create a new method applyStaffDiscount here
    applyStaffDiscount: function(employee){
        this.total -= this.total * (employee.discountPercent * 0.01);
    },
    
};
cashRegister.scan('eggs',1);
cashRegister.scan('milk',1);
cashRegister.scan('magazine',3);
// Apply your staff discount by passing the 'me' object 
// to applyStaffDiscount
cashRegister.applyStaffDiscount(me);
// Show the total bill
console.log('Your bill is '+cashRegister.total.toFixed(2));